home *** CD-ROM | disk | FTP | other *** search
- UNIT TidyWinB;
- (**) INTERFACE (**)
- USES WinTypes, WinProcs, Strings, Win31, TidyWinA,
- {$IFDEF VER70} ODialogs, OWindows, Objects;
- {$ELSE} WObjects; {$ENDIF}
- CONST
- ServerName = 'PROGMAN';
- TopicName = 'PROGMAN';
- GroupSect = 'Groups';
- ProgmanSect = 'Progman.Itself';
- {DDE constants}
- fResponse = $1000;
- fRelease = $2000;
- reserved = $4000;
- fAckReq = $8000;
- TYPE
- PTidyWindowB = ^TTidyWindowB;
- TTidyWindowB = OBJECT(TTidyWindowA)
- LinkedToPM : Boolean;
- IniName : PChar;
- TAserver,
- TAtopic, TAGroup : TAtom;
- CurrGrp : Word;
- CONSTRUCTOR Init(AParent : PWindowsObject; AName : PChar);
- DESTRUCTOR Done; Virtual;
- FUNCTION CanClose : Boolean; Virtual;
- PROCEDURE SaveLayout;
- PROCEDURE InitDDEConversation;
- PROCEDURE Converse; Virtual;
- PROCEDURE wmDDEAck(VAR Msg : TMessage); Virtual
- wm_First + wm_DDE_Ack;
- PROCEDURE wmDDEData(VAR Msg : TMessage); Virtual
- wm_First + wm_DDE_Data;
- PROCEDURE wmDDETerminate(VAR Msg : TMessage); Virtual
- wm_First + wm_DDE_Terminate;
- END;
-
- (**) IMPLEMENTATION (**)
- CONSTRUCTOR TTidyWindowB.Init(AParent : PWindowsObject;
- AName : PChar);
- BEGIN
- TTidyWindowA.Init(AParent, AName);
- LinkedToPM := FALSE;
- END;
-
- DESTRUCTOR TTidyWindowB.Done;
- BEGIN
- IF LinkedToPM THEN PostMessage(PMWindow, wm_DDE_Terminate,
- hWindow, 0);
- TTidyWindowA.Done;
- END;
-
- FUNCTION TTidyWindowB.CanClose : Boolean;
- BEGIN
- IF LinkedToPM THEN
- BEGIN
- CanClose := FALSE;
- IF NOT Quiet THEN MessageBeep(mb_IconInformation);
- MessageBox(hWindow, 'Patience - DDE conversation still '+
- 'in progress.', 'WINTIDY', mb_OK + mb_IconInformation);
- END
- ELSE CanClose := TRUE;
- END;
-
- PROCEDURE TTidyWindowB.SaveLayout;
- VAR N : Word;
-
- PROCEDURE ClearIniFile;
- CONST bSize = MaxGroups*50; {est. max 50 chars per name}
- VAR SecBuff, P : PChar;
- BEGIN
- GetMem(SecBuff, bSize);
- {fill SecBuff with all keys from Groups section, separated by
- #0 and ending with a double #0}
- GetPrivateProfileString(GroupSect, NIL, '', SecBuff,
- bSize, IniName);
- P := SecBuff;
- {"walk" P through the list}
- WHILE P[0] <> #0 DO
- BEGIN
- {Clear items section for this group}
- WritePrivateProfileString(P, NIL, NIL, IniName);
- P := StrEnd(P) + 1;
- END;
- FreeMem(SecBuff, bSize);
- {Clear the existing Groups section}
- WritePrivateProfileString(GroupSect, NIL, NIL, IniName);
- {Clear the ProgMan section}
- WritePrivateProfileString(ProgmanSect, NIL, NIL,
- IniName);
- END;
-
- PROCEDURE WriteOneLocation(IsGroup : Boolean; H : HWnd);
- CONST
- nBSize = 80;
- tBSize = 60;
- VAR
- NameBuf : ARRAY[0..nBSize] OF Char;
- Sect : PChar;
- TWP : TWindowPlacement;
- TWPbuf : ARRAY[0..tBSize] OF Char;
- BEGIN
- IF IsGroup THEN
- BEGIN
- GetWindowText(H, NameBuf, nBSize);
- Sect := GroupSect;
- END
- ELSE
- BEGIN
- StrCopy(NameBuf, 'Placement');
- Sect := ProgmanSect;
- END;
- {Must set TWP.length before calling GetWindowPlacement}
- TWP.length := SizeOf(TWP);
- GetWindowPlacement(H, @TWP);
- wvsprintf(TWPBuf, '%u;%u;%u,%u;%u,%u;%u,%u,%u,%u', TWP.flags);
- WritePrivateProfileString(Sect, NameBuf, TWPBuf, IniName);
- END;
-
- BEGIN
- IF pmWindow = 0 THEN Exit;
- OldCur := SetCursor(LoadCursor(0, idc_Wait));
- SetCapture(hWindow);
- ClearIniFile;
- GetGroupHandles;
- {write location data for each group window, and ProgMan too}
- FOR N := 1 TO THA[0] DO WriteOneLocation(TRUE, THA[N]);
- WriteOneLocation(FALSE, PMWindow);
- CurrGrp := 0;
- InitDDEConversation;
- END;
-
- PROCEDURE TTidyWindowB.InitDDEConversation;
- BEGIN
- {initiate a DDE conversation with ProgMan}
- TAserver := GlobalAddAtom(ServerName);
- TATopic := GlobalAddAtom(TopicName);
- {ProgMan will respond with wm_DDE_Ack}
- SendMessage(pmWindow, wm_DDE_Initiate, hWindow,
- MakeLong(TAserver, TAtopic));
- GlobalDeleteAtom(TAtopic);
- GlobalDeleteAtom(TAserver);
- END;
-
- PROCEDURE TTidyWindowB.wmDDEAck(VAR Msg : TMessage);
- {Should receive one Ack upon initiating conversation.}
- BEGIN
- IF NOT LinkedToPM THEN
- BEGIN
- LinkedToPM := TRUE;
- TAserver := Msg.LParamLo;
- TAtopic := Msg.LParamHi;
- PMWindow := Msg.wParam;
- IF TAserver <> 0 THEN GlobalDeleteAtom(TAserver);
- IF TAtopic <> 0 THEN GlobalDeleteAtom(TAtopic);
- Converse;
- END
- ELSE
- BEGIN
- IF (Msg.LParamLo AND dde_Ack) <> dde_Ack THEN
- BEGIN
- IF NOT Quiet THEN MessageBeep(mb_IconStop);
- MessageBox(hWindow, 'Program Manager does not'+
- ' acknowledge command', 'ERROR',
- mb_Ok + mb_IconStop);
- SetCursor(OldCur);
- ReleaseCapture;
- END;
- GlobalDeleteAtom(Msg.lParamHi);
- END;
- END;
-
- PROCEDURE TTidyWindowB.Converse;
- CONST nBSize = 80;
- VAR NameBuf : ARRAY[0..nBSize] OF Char;
- BEGIN
- Inc(CurrGrp);
- IF CurrGrp <= THA[0] THEN
- BEGIN
- GetWindowText(THA[CurrGrp], NameBuf, nBSize);
- TAGroup := GlobalAddAtom(NameBuf);
- {ProgMan will respond with wm_DDE_Data}
- PostMessage(PMWindow, wm_DDE_Request, hWindow,
- MakeLong(cf_Text, TAGroup));
- END
- ELSE
- BEGIN
- IF NOT Quiet THEN MessageBeep(mb_IconInformation);
- MessageBox(hWindow, 'Layout has been saved in INI file',
- IniName, mb_Ok + mb_IconInformation);
- PostMessage(PMWindow, wm_DDE_Terminate, hWindow, 0);
- SetCursor(OldCur);
- ReleaseCapture;
- END;
- END;
-
- PROCEDURE TTidyWindowB.wmDDEData(VAR Msg : TMessage);
- VAR
- PTD : PDDEData;
- Release : Boolean;
- PData, GrpName,
- ItemP, NextItem,
- NameP : PChar;
- Len, M : Word;
- BEGIN
- PTD := GlobalLock(Msg.lParamLo);
- Release := PTD^.Flags AND fRelease > 0;
- GlobalDeleteAtom(Msg.lParamHi);
- PData := @PTD^.Value;
- Len := StrLen(PData);
- {replace CR/LF with #0#0, so can use StrEnd to "walk" the list}
- FOR M := 0 TO pred(Len) DO
- IF (PData[M] = #13) OR (PData[M] = #10) THEN
- PData[M] := #0;
- {point ItemP to first line of ITEM data, after GROUP data}
- ItemP := StrEnd(PData)+2;
- {point GrpName past initial quotemark...}
- GrpName := PData+1;
- {... and chop it off at next quotemark}
- StrScan(GrpName, '"')^ := #0;
- {If ItemP empty, there *ARE* no items}
- IF ItemP[0] = #0 THEN
- BEGIN
- IF NOT Quiet THEN MessageBeep(mb_IconInformation);
- MessageBox(hWindow, 'Note: Group contains NO program items',
- GrpName, mb_Ok + mb_IconInformation);
- END
- ELSE
- {now record the individual item data}
- REPEAT
- {Note location of NEXT item before we chop up this item}
- NextItem := StrEnd(ItemP)+2;
- NameP := ItemP+1; {skip initial quotemark}
- ItemP := StrScan(NameP, '"') + 2;
- {NameP points to item name - chop it off at quote}
- StrScan(NameP,'"')^ := #0;
- {ItemP points at path after quoted name. skip over three
- commas to reach location data}
- ItemP := StrScan(ItemP, ',')+1;
- ItemP := StrScan(ItemP, ',')+1;
- ItemP := StrScan(ItemP, ',')+1;
- {insert #0 at 2nd comma}
- StrScan(StrScan(ItemP, ',')+1, ',')^ := #0;
- {record item name as key, location as value}
- WritePrivateProfileString(GrpName, NameP, ItemP, IniName);
- ItemP := NextItem;
- UNTIL ItemP-PData >= Len;
- GlobalUnlock(Msg.lParamLo);
- IF Release THEN GlobalFree(Msg.lParamLo);
- Converse;
- END;
-
- PROCEDURE TTidyWindowB.wmDDETerminate(VAR Msg:TMessage);
- BEGIN
- LinkedToPM := FALSE;
- END;
- END.
-